package jmine.tec.security.web.test;

import java.security.Principal;
import java.util.HashSet;
import java.util.Set;

import javax.security.auth.Subject;

import bancosys.tec.persist.dao.BaseDAO;
import bancosys.tec.security.SecurityException;
import bancosys.tec.security.authorization.Permission;
import bancosys.tec.security.impl.AbstractSecurityManager;
import bancosys.tec.security.impl.SecurityPrincipal;
import bancosys.tec.security.impl.domain.Credential;
import bancosys.tec.security.impl.web.WebSecurityContext;
import bancosys.tec.security.impl.web.WebSecurityManager;

/**
 * SecurityManager que dá todas as credenciais disponíveis ao usuário "A" com senha "A".
 * 
 * @author lundberg
 */
public class AARootSecurityManager extends AbstractSecurityManager<WebSecurityContext> implements WebSecurityManager {

    /**
     * {@inheritDoc}
     */
    public Subject loadSubject(WebSecurityContext context) throws SecurityException {
        return (Subject) context.getRequest().getSession().getAttribute(SESSION_KEY);
    }

    /**
     * {@inheritDoc}
     */
    public Subject login(String username, String password, WebSecurityContext context) throws SecurityException {
        this.getTransactionalController().startTransaction();
        boolean success = false;
        Subject subject = null;
        try {
            if ("A".equalsIgnoreCase(username) && "A".equalsIgnoreCase(password)) {
                subject = this.createSubject();
            }
            success = true;
        } finally {
            if (success) {
                this.getTransactionalController().commit();
            } else {
                this.getTransactionalController().rollback();
            }
        }
        return subject;
    }

    /**
     * Cria o subject
     * 
     * @return Subject
     */
    private Subject createSubject() {
        Set<? extends Permission> pubCredentials = this.getPubCredentials();
        Set<? extends Permission> privCredentials = new HashSet<Permission>();
        Set<Principal> principals = new HashSet<Principal>();
        principals.add(new SecurityPrincipal("A"));

        return new Subject(true, principals, pubCredentials, privCredentials);
    }

    /**
     * Busca todas as credenciais disponíveis na base.
     * 
     * @return Set
     */
    private Set<? extends Permission> getPubCredentials() {
        Set<Permission> pubCredentials = new HashSet<Permission>();
        BaseDAO<Credential> dao = this.getTransactionalController().getDAOFactory().getGenericDAO(Credential.class);
        for (Credential credential : dao.findAll()) {
            pubCredentials.add(credential.createPermission());
        }
        return pubCredentials;
    }

    /**
     * {@inheritDoc}
     */
    public void logout(WebSecurityContext context) {
        context.getRequest().getSession().removeAttribute(SESSION_KEY);
    }

    /**
     * {@inheritDoc}
     */
    public void storeSubject(WebSecurityContext context, Subject subject) {
        context.getRequest().getSession().setAttribute(SESSION_KEY, subject);
    }

}
